package sms_api

import (
	"fmt"
	"time"
)

// SMSError 定义SMS API的错误接口
type SMSError interface {
	error
	Code() string
	Message() string
	Details() map[string]interface{}
	Timestamp() time.Time
	Retryable() bool
}

// BaseError 基础错误结构体
type BaseError struct {
	code      string
	message   string
	details   map[string]interface{}
	timestamp time.Time
	retryable bool
	cause     error
}

// Error 实现error接口
func (e *BaseError) Error() string {
	if e.cause != nil {
		return fmt.Sprintf("%s: %s (caused by: %v)", e.code, e.message, e.cause)
	}
	return fmt.Sprintf("%s: %s", e.code, e.message)
}

// Code 返回错误代码
func (e *BaseError) Code() string {
	return e.code
}

// Message 返回错误消息
func (e *BaseError) Message() string {
	return e.message
}

// Details 返回错误详情
func (e *BaseError) Details() map[string]interface{} {
	if e.details == nil {
		return make(map[string]interface{})
	}
	return e.details
}

// Timestamp 返回错误发生时间
func (e *BaseError) Timestamp() time.Time {
	return e.timestamp
}

// Retryable 返回是否可重试
func (e *BaseError) Retryable() bool {
	return e.retryable
}

// Cause 返回原始错误
func (e *BaseError) Cause() error {
	return e.cause
}

// Unwrap 支持errors.Unwrap
func (e *BaseError) Unwrap() error {
	return e.cause
}

// WithDetail 添加错误详情
func (e *BaseError) WithDetail(key string, value interface{}) *BaseError {
	if e.details == nil {
		e.details = make(map[string]interface{})
	}
	e.details[key] = value
	return e
}

// WithCause 设置原始错误
func (e *BaseError) WithCause(cause error) *BaseError {
	e.cause = cause
	return e
}

// ValidationError 参数验证错误
type ValidationError struct {
	*BaseError
	field string
	value interface{}
	rule  string
}

// NewValidationError 创建参数验证错误
func NewValidationError(field, rule string, value interface{}, message string) *ValidationError {
	return &ValidationError{
		BaseError: &BaseError{
			code:      ErrCodeValidationError,
			message:   message,
			timestamp: time.Now(),
			retryable: false,
			details: map[string]interface{}{
				"field": field,
				"value": value,
				"rule":  rule,
			},
		},
		field: field,
		value: value,
		rule:  rule,
	}
}

// Field 返回验证失败的字段
func (e *ValidationError) Field() string {
	return e.field
}

// Value 返回验证失败的值
func (e *ValidationError) Value() interface{} {
	return e.value
}

// Rule 返回验证规则
func (e *ValidationError) Rule() string {
	return e.rule
}

// ProviderError SMS提供商错误
type ProviderError struct {
	*BaseError
	provider     string
	providerCode string
	providerMsg  string
}

// NewProviderError 创建提供商错误
func NewProviderError(provider, providerCode, providerMsg string, retryable bool) *ProviderError {
	return &ProviderError{
		BaseError: &BaseError{
			code:      ErrCodeProviderError,
			message:   fmt.Sprintf("Provider %s error: %s", provider, providerMsg),
			timestamp: time.Now(),
			retryable: retryable,
			details: map[string]interface{}{
				"provider":      provider,
				"provider_code": providerCode,
				"provider_msg":  providerMsg,
			},
		},
		provider:     provider,
		providerCode: providerCode,
		providerMsg:  providerMsg,
	}
}

// Provider 返回提供商名称
func (e *ProviderError) Provider() string {
	return e.provider
}

// ProviderCode 返回提供商错误代码
func (e *ProviderError) ProviderCode() string {
	return e.providerCode
}

// ProviderMessage 返回提供商错误消息
func (e *ProviderError) ProviderMessage() string {
	return e.providerMsg
}

// NetworkError 网络错误
type NetworkError struct {
	*BaseError
	url        string
	method     string
	statusCode int
	latency    time.Duration
}

// NewNetworkError 创建网络错误
func NewNetworkError(url, method string, statusCode int, latency time.Duration, cause error) *NetworkError {
	message := fmt.Sprintf("Network error: %s %s (status: %d, latency: %v)", method, url, statusCode, latency)
	retryable := statusCode >= 500 || statusCode == 429 || statusCode == 408
	
	return &NetworkError{
		BaseError: &BaseError{
			code:      ErrCodeNetworkError,
			message:   message,
			timestamp: time.Now(),
			retryable: retryable,
			cause:     cause,
			details: map[string]interface{}{
				"url":         url,
				"method":      method,
				"status_code": statusCode,
				"latency":     latency,
			},
		},
		url:        url,
		method:     method,
		statusCode: statusCode,
		latency:    latency,
	}
}

// URL 返回请求URL
func (e *NetworkError) URL() string {
	return e.url
}

// Method 返回HTTP方法
func (e *NetworkError) Method() string {
	return e.method
}

// StatusCode 返回HTTP状态码
func (e *NetworkError) StatusCode() int {
	return e.statusCode
}

// Latency 返回请求延迟
func (e *NetworkError) Latency() time.Duration {
	return e.latency
}

// RateLimitError 速率限制错误
type RateLimitError struct {
	*BaseError
	limit     int
	remaining int
	resetTime time.Time
}

// NewRateLimitError 创建速率限制错误
func NewRateLimitError(limit, remaining int, resetTime time.Time) *RateLimitError {
	message := fmt.Sprintf("Rate limit exceeded: %d/%d, reset at %v", remaining, limit, resetTime)
	
	return &RateLimitError{
		BaseError: &BaseError{
			code:      ErrCodeRateLimit,
			message:   message,
			timestamp: time.Now(),
			retryable: true,
			details: map[string]interface{}{
				"limit":      limit,
				"remaining":  remaining,
				"reset_time": resetTime,
			},
		},
		limit:     limit,
		remaining: remaining,
		resetTime: resetTime,
	}
}

// Limit 返回速率限制
func (e *RateLimitError) Limit() int {
	return e.limit
}

// Remaining 返回剩余次数
func (e *RateLimitError) Remaining() int {
	return e.remaining
}

// ResetTime 返回重置时间
func (e *RateLimitError) ResetTime() time.Time {
	return e.resetTime
}

// CircuitOpenError 熔断器开启错误
type CircuitOpenError struct {
	*BaseError
	failureCount int
	lastFailure  time.Time
	nextAttempt  time.Time
}

// NewCircuitOpenError 创建熔断器开启错误
func NewCircuitOpenError(failureCount int, lastFailure, nextAttempt time.Time) *CircuitOpenError {
	message := fmt.Sprintf("Circuit breaker is open: %d failures, next attempt at %v", failureCount, nextAttempt)
	
	return &CircuitOpenError{
		BaseError: &BaseError{
			code:      ErrCodeCircuitOpen,
			message:   message,
			timestamp: time.Now(),
			retryable: false,
			details: map[string]interface{}{
				"failure_count": failureCount,
				"last_failure":  lastFailure,
				"next_attempt":  nextAttempt,
			},
		},
		failureCount: failureCount,
		lastFailure:  lastFailure,
		nextAttempt:  nextAttempt,
	}
}

// FailureCount 返回失败次数
func (e *CircuitOpenError) FailureCount() int {
	return e.failureCount
}

// LastFailure 返回最后失败时间
func (e *CircuitOpenError) LastFailure() time.Time {
	return e.lastFailure
}

// NextAttempt 返回下次尝试时间
func (e *CircuitOpenError) NextAttempt() time.Time {
	return e.nextAttempt
}

// TimeoutError 超时错误
type TimeoutError struct {
	*BaseError
	timeout time.Duration
	operation string
}

// NewTimeoutError 创建超时错误
func NewTimeoutError(operation string, timeout time.Duration) *TimeoutError {
	message := fmt.Sprintf("Operation %s timed out after %v", operation, timeout)
	
	return &TimeoutError{
		BaseError: &BaseError{
			code:      ErrCodeTimeout,
			message:   message,
			timestamp: time.Now(),
			retryable: true,
			details: map[string]interface{}{
				"operation": operation,
				"timeout":   timeout,
			},
		},
		timeout:   timeout,
		operation: operation,
	}
}

// Timeout 返回超时时间
func (e *TimeoutError) Timeout() time.Duration {
	return e.timeout
}

// Operation 返回操作名称
func (e *TimeoutError) Operation() string {
	return e.operation
}

// 便捷的错误创建函数

// NewInvalidPhoneError 创建无效手机号错误
func NewInvalidPhoneError(phone string) *ValidationError {
	return NewValidationError("phone", "format", phone, "手机号格式无效")
}

// NewInvalidContentError 创建无效内容错误
func NewInvalidContentError(content string, reason string) *ValidationError {
	return NewValidationError("content", "format", content, fmt.Sprintf("短信内容无效: %s", reason))
}

// NewInvalidSignError 创建无效签名错误
func NewInvalidSignError(sign string) *ValidationError {
	return NewValidationError("sign", "format", sign, "短信签名无效")
}

// NewInsufficientQuotaError 创建余额不足错误
func NewInsufficientQuotaError(provider string) *ProviderError {
	return NewProviderError(provider, ErrCodeInsufficientQuota, "短信余额不足", false)
}

// NewBlacklistPhoneError 创建黑名单手机号错误
func NewBlacklistPhoneError(phone string) *ProviderError {
	return NewProviderError("system", ErrCodeBlacklistPhone, fmt.Sprintf("手机号 %s 在黑名单中", phone), false)
}

// NewTemplateNotFoundError 创建模板不存在错误
func NewTemplateNotFoundError(templateID string) *ProviderError {
	return NewProviderError("system", ErrCodeTemplateNotFound, fmt.Sprintf("短信模板 %s 不存在", templateID), false)
}

// IsRetryableError 判断错误是否可重试
func IsRetryableError(err error) bool {
	if smsErr, ok := err.(SMSError); ok {
		return smsErr.Retryable()
	}
	return false
}

// GetErrorCode 获取错误代码
func GetErrorCode(err error) string {
	if smsErr, ok := err.(SMSError); ok {
		return smsErr.Code()
	}
	return ErrCodeInternalError
}

// GetErrorDetails 获取错误详情
func GetErrorDetails(err error) map[string]interface{} {
	if smsErr, ok := err.(SMSError); ok {
		return smsErr.Details()
	}
	return map[string]interface{}{
		"error": err.Error(),
	}
}